Scriptia. Javascript y buenas prácticas en español



Scriptia / Etiquetas / or

Saltar a Acerca de Scriptia

Estás viendo la página para la etiqueta (o conjunto de etiquetas) or .

Etiquetas relacionadas: |

Eventos en jQuery 1.2

Días ha que escribí una nota sobre los eventos en jQuery. Y hora es de ampliar dicho artículo con las novedades que la serie 1.2 de jQuery añade al respecto.

Lo de siempre

Recordemos las bases de la asignación y el manejo de eventos en jQuery. La forma básica de asignar un manejador es la siguiente:

$('un.selector')
  .bind('click', unaFuncion);

El manejador (unaFuncion) recibe como parámetro el objeto que representa el evento (normalizado para tener acceso común a sus propiedades en los distintos navegadores). La función se ejecuta en el contexto del elemento al que se ha asignado el manejador.

function unaFuncion(e) {
    console.log('Contexto', this);
    console.log('Evento', e);
}

$('un.selector')
    .bind('click', unaFuncion);

Lo nuevo

Con jQuery 1.2 podemos asignar un manejador para varios eventos con una sola llamada a bind(). Utilizamos para ello una lista de nombres de evento separados por espacios. Observa que en el manejador tomamos una decisión basada en la propiedad type del objeto del evento.

function handle(e) {
  var $label = $(this).prev();
  if (e.type == 'focus') {
    $label.hide();
  }
  else if (this.value == '') {
    $label.show();
  }
}

$('#login input')
  .filter('[type=text], [type=password]')
    .bind('focus blur', handle);

Otra novedad interesante es la pseudonombrespaciación de eventos, que se puede practicar utilizando el nombre del evento seguido de un punto y un identificador arbitrario al asignar el manejador.

Y esto, ¿para qué? Para facilitar la eliminación de grupos de manejadores.

// en algún lugar del código de un drag'n'drop
$(document)
  .bind('mousemove.rock_n_roll', some_handler)
  .bind('mouseup.rock_n_roll', mouseup_handler);

// en el código de finalización del arrastre
$(document)
  .unbind('.rock_n_roll');

Y algo que no es exactamente nuevo pero mola todo y se conoce poco: podemos pasar un objeto de datos en la asignación. El manejador lo recibirá en la propiedad data del evento.

function handle_click(e) {
  alert(e.data.foo);
}

$.fn.somePlugin(opts) {
  var settings = $.extend({
    foo: 'bar'
  });
  this.bind('click', settings, handle_click);
  return this;
}

// mostrará "bar" al activar los enlaces
// con clase "tigre"
$('a.tigre').somePlugin();

// mostrará "tolo" al activar los enlaces
// con clase "leon"
$('a.leon').somePlugin({ foo: 'tolo' });

Por último, se incorpora a la API el método triggerHandler que complementa a trigger. La diferencia: triggerHandler dispara los manejadores asignados al evento pero no ejecuta las acciones por defecto del navegador.

Para más y mejor información y, de paso, practicar el inglés: Release: jQuery 1.2/Events.

Ajax, eventos y jQuery

Un «problema» con el que todo novato de la programación con jQuery se encuentra tarde o temprano (y las listas de correo lo demuestran) es que el contenido cargado (o generado) dinámicamente no dispara los manejadores de eventos asignados en $(document).ready.

Y, hoygan, esto es de lo más normal.

Si repasamos nuestra forma habitual de trabajar con jQuery, y reflexionamos un poquito…

$(document).ready(function() {
  $('selecciono.algo')
    .bind('click', hazCosasBonitas);
});

… recordaremos que estamos utilizando $(document).ready porque no podemos seleccionar elementos que no existen. De ahí que tengamos que esperar a disponer de un árbol DOM completo. De ahí que los manejadores de eventos no afecten a elementos nuevos.

¿Entonces?

Opciones las hay adecuadas a unos casos y a otros. La más sencilla, para casos sencillos, es inicializar los contenidos nuevos una vez los hayamos insertado en el documento.

Necesitamos, pues, una función que nos permita seleccionar y actuar dentro de un contexto. Recuerda que jQuery provee de selecciones basadas en contexto. Si utilizas

$('a');

seleccionarás todos los enlaces del documento. Pero si usas

$('a', unElementoSelecto);

seleccionarás los enlaces descendientes de unElementoSelecto.

Por tanto, podemos crear nuestra función de inicialización según contexto como sigue.

function initLinks(context) {
  $('a', context)
    .bind('click', hazCosasBonitas)
}

Que ejecutaremos desde nuestro manejador para $(document).ready, pasando el documento como contexto de búsqueda:

$(document).ready(function() {
  initLinks(document);
});

Así que estamos como al principio… pero mucho más cerca del final. Lo único que nos queda por hacer es ejecutar initLinks cuando recuperemos nuevo contenido. Si usamos load, el más simplón de los métodos Ajax de jQuery, basta con usar una función de callback:

function loadNewContent() {
  $('#holder').load('ajax-content.html #response p', function() {
    // `this` apunta al elemento que acabamos de rellenar
    initLinks(this);
  });  
}

Y esta es la idea básica, que he reflejado en esta pequeña demo en latín.

Por supuesto, hay otras opciones. Si eres de los que para clavar un clavo usa un plugin, échale un vistazo a LiveQuery; si tienes un serio trasiego de elementos vivos, mejor apostar por la delegación de eventos. Pero esas son otras historias que contaré a su debido momento.

Los locos locos eventos de teclado

En lo que hace a eventos, los navegadores suelen ir a su bola. Y en lo que hace a eventos de teclado, el caos es absoluto: hay quien notifica las teclas modificadores en keypress, hay quien no; cada navegador es un mundo en cuanto a códigos de tecla… y dos o tres pesadillas más.

En JavaScript Madness: Keyboard Events, Jan Wolter documenta para uso y disfrute público todas las divergencias que se va encontrando.

jQuery 1.1.3: igual de ligera, más rápida

Amigos: ya está aquí la versión 1.1.3 de mi biblioteca favorita. Novedades: mejora en el sistema de eventos, nuevos selectores (y la recuperación de ~= como selector por atributos con valores separados por espacios), mejoras en las animaciones y, chan ta ta chan, mejoras en la velocidad de la selección de nodos de hasta un 800%.

Léanlo todo, amigos míos, en jQuery 1.1.3: 800%+ Faster, still 20KB.

Árbol desplegable en jQuery

Un clásico entre los clásicos, la presentación de listas anidadas en forma de árbol desplegable, ya tiene un buen representante escrito con y para jQuery. jQuery plugin: Treeview, una criatura de Jörn Zaefferer.

Clonado de eventos en jQuery

Ya trabajas con jQuery y dominas el arte de clonar elementos. Pero, cielos, un elemento clonado no conserva los manejadores de eventos asignados al original. Brandon Aaron nos presenta su solución en Copy Events from One Element to Another, publicado en Learning jQuery.

onbeforeunload: tiende una mano al usuario

¿Alguna vez has cerrado una ventana cuando tenías un formulario a medio rellenar? ¿Has invertido media hora en escribir un email y, por error, has abandonado la página sin enviarlo? Evita a tus usuarios pasar por este trauma –y el de aprender hebreo– usando onbeforeunload. Continúa leyendo onbeforeunload: tiende una mano al usuario

Eventos en jQuery

Presentamos un repaso en profundidad a los métodos de jQuery relacionados con el trabajo con eventos: asignación, manejo (this y target), desligado de manejadores, disparo artificial de eventos, atajos y buen humor. Continúa leyendo Eventos en jQuery

Bloqueo de interacción

Directamente desde la lista de jQuery, un plugin que permite bloquear la interacción del usuario sin freir el navegador: jQuery blockUI/unblockUI. Ideal para peticiones AJAX.

Referencia de eventos DOM en la Wikipedia

Eventos DOM –estándares y propietarios– correctamente descritos en DOM events (Wikipedia).

Acerca de Scriptia

Saltar a la caja de búsqueda

Scriptia forma parte del PDM de Choan C. Gálvez, desarrollador web residente en Barcelona. Scriptia pretende mejorar la calidad de la documentación acerca de javascript disponible en español.